package com.onenine.chat.rongcloud;

import android.net.Uri;
import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.onenine.app.db.DataManager;
import com.onenine.app.model.GameTextMessage;
import com.onenine.base.utils.AppConfig;
import com.onenine.chat.commons.IConversation;
import com.onenine.chat.commons.IUser;
import com.onenine.chat.model.LBroadcast;
import com.onenine.chat.model.LConversation;
import com.onenine.chat.model.LUser;
import com.onenine.chat.model.RcExtra;
import com.onenine.common.util.Logger;
import com.onenine.common.util.TimeUtils;

import org.greenrobot.eventbus.EventBus;
import org.litepal.crud.DataSupport;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import io.rong.imlib.IRongCallback;
import io.rong.imlib.MessageTag;
import io.rong.imlib.RongIMClient;
import io.rong.imlib.model.Conversation;
import io.rong.imlib.model.Message;
import io.rong.imlib.model.MessageContent;
import io.rong.message.GroupNotificationMessage;
import io.rong.message.ImageMessage;
import io.rong.message.InformationNotificationMessage;
import io.rong.message.TextMessage;
import io.rong.message.VoiceMessage;

/**
 * 创建时间：2018/5/31 0031 9:32
 * 创建人：fly
 * 功能描述：融云通信管理
 */
public class RcImMgr {

    public static final String FILE_SCHEMA = "file://";
    public static final int CALL_NOTIFICATION_ID = 4000;
    private static RcImMgr mImMgr;

    public interface OnMessageListener {
        void onSuccess(Message message);

        void onProgress(Message message);

        void onFailure(RongIMClient.ErrorCode errorCode);
    }

    public interface OnConversationListener {
        void onResult(List<LConversation> lConversations);

        void onError(RongIMClient.ErrorCode errorCode);
    }

    private RcImMgr() {
    }

    public static RcImMgr getInstance() {
        if (mImMgr == null) {
            synchronized (RcImMgr.class) {
                if (mImMgr == null) {
                    mImMgr = new RcImMgr();
                }
            }
        }
        return mImMgr;
    }

    public static void setOnMessageReceiveListener(RongIMClient.OnReceiveMessageListener onMessageReceiveListener) {
        RongIMClient.setOnReceiveMessageListener(onMessageReceiveListener);
    }

    /**
     * 发送群信息小灰条
     *
     * @param targetId
     * @param content
     */
    public void sendGroupMgrInfoMessage(String targetId, String content) {
        InformationNotificationMessage inMessage = InformationNotificationMessage.obtain(content);
        RongIMClient.getInstance().sendMessage(Conversation.ConversationType.GROUP, targetId
                , inMessage, null, null, new IRongCallback.ISendMessageCallback() {
                    @Override
                    public void onAttached(Message message) {

                    }

                    @Override
                    public void onSuccess(Message message) {
                        Logger.e("群管理消息发送成功");
                    }

                    @Override
                    public void onError(Message message, RongIMClient.ErrorCode errorCode) {
                        Logger.e("群管理消息发送失败");
                    }
                });
    }

    /**
     * 发送群组创建消息
     *
     * @param targetId
     * @param messageListener
     */
    public void sendGroupCreateMessage(String targetId, final OnMessageListener messageListener) {
        GroupNotificationMessage message = GroupNotificationMessage.obtain(RcUser.getInstance().getUserId()
                , GroupNotificationMessage.GROUP_OPERATION_CREATE, null, null);
        RongIMClient.getInstance().sendMessage(Conversation.ConversationType.GROUP, targetId
                , message, null, null, new IRongCallback.ISendMessageCallback() {

                    @Override
                    public void onAttached(Message message) {
                        if (messageListener != null) {
                            messageListener.onProgress(message);
                        }
                    }

                    @Override
                    public void onSuccess(Message message) {
                        if (messageListener != null) {
                            messageListener.onSuccess(message);
                        }
                    }

                    @Override
                    public void onError(Message message, RongIMClient.ErrorCode errorCode) {
                        if (messageListener != null) {
                            messageListener.onFailure(errorCode);
                        }
                    }
                });
    }

    /**
     * 发送群组解散消息
     *
     * @param targetId
     * @param messageListener
     */
    public void sendGroupRenameMessage(String targetId, GroupNotificationMessage notificationMessage, final OnMessageListener messageListener) {
        RongIMClient.getInstance().sendMessage(Conversation.ConversationType.GROUP, targetId
                , notificationMessage, null, null, new IRongCallback.ISendMessageCallback() {

                    @Override
                    public void onAttached(Message message) {
                        if (messageListener != null) {
                            messageListener.onProgress(message);
                        }
                    }

                    @Override
                    public void onSuccess(Message message) {
                        Logger.e("群更名消息发送成功");
                        if (messageListener != null) {
                            messageListener.onSuccess(message);
                        }
                    }

                    @Override
                    public void onError(Message message, RongIMClient.ErrorCode errorCode) {
                        Logger.e("群更名消息发送失败");
                        if (messageListener != null) {
                            messageListener.onFailure(errorCode);
                        }
                    }
                });
    }

    /**
     * 发送群组解散消息
     *
     * @param targetId
     * @param messageListener
     */
    public void sendGroupDismissMessage(String targetId, final OnMessageListener messageListener) {
        GroupNotificationMessage message = GroupNotificationMessage.obtain(RcUser.getInstance().getUserId()
                , GroupNotificationMessage.GROUP_OPERATION_DISMISS, null, null);
        RongIMClient.getInstance().sendMessage(Conversation.ConversationType.GROUP, targetId
                , message, null, null, new IRongCallback.ISendMessageCallback() {

                    @Override
                    public void onAttached(Message message) {
                        Logger.e("群解散消息发送中:" + message.getSentStatus());
                        if (messageListener != null) {
                            messageListener.onProgress(message);
                        }
                    }

                    @Override
                    public void onSuccess(Message message) {
                        Logger.e("群解散消息发送成功");
                        if (messageListener != null) {
                            messageListener.onSuccess(message);
                        }
                    }

                    @Override
                    public void onError(Message message, RongIMClient.ErrorCode errorCode) {
                        Logger.e("群解散消息发送失败");
                        if (messageListener != null) {
                            messageListener.onFailure(errorCode);
                        }
                    }
                });
    }

    /**
     * 发送自定义消息
     *
     * @param type
     * @param targetId
     * @param messageContent
     * @param messageListener
     */
    public void sendCustomMessage(Conversation.ConversationType type, String targetId, MessageContent messageContent
            , final OnMessageListener messageListener) {
        RongIMClient.getInstance().sendMessage(type, targetId, messageContent, null, null
                , new IRongCallback.ISendMessageCallback() {
                    @Override
                    public void onAttached(Message message) {
                        Logger.e("自定义消息发送中:" + message.getSentStatus());
                        if (messageListener != null) {
                            messageListener.onProgress(message);
                        }
                    }

                    @Override
                    public void onSuccess(Message message) {
                        Logger.e("自定义消息发送成功");
                        if (messageListener != null) {
                            messageListener.onSuccess(message);
                        }
                    }

                    @Override
                    public void onError(Message message, RongIMClient.ErrorCode errorCode) {
                        Logger.e("自定义消息发送失败:" + errorCode.getValue() + "," + errorCode.getMessage());
                        if (messageListener != null) {
                            messageListener.onFailure(errorCode);
                        }
                    }
                });
    }


    /**
     * 发送带附加信息的文本消息
     *
     * @param type
     * @param targetId
     * @param text
     * @param extra
     * @param messageListener
     */
    public void sendTextMessage(Conversation.ConversationType type, String targetId
            , String text, RcExtra extra, final OnMessageListener messageListener) {
        TextMessage textMessage = TextMessage.obtain(text);
        if (extra != null) {
            textMessage.setExtra(JSON.toJSONString(extra));
        }
        RongIMClient.getInstance().sendMessage(type, targetId, textMessage, null, null, new IRongCallback.ISendMessageCallback() {
            @Override
            public void onAttached(Message message) {
                Logger.e("文本消息发送中:" + message.getSentStatus());
                if (messageListener != null) {
                    messageListener.onProgress(message);
                }
            }

            @Override
            public void onSuccess(Message message) {
                Logger.e("文本消息发送成功");
                if (messageListener != null) {
                    messageListener.onSuccess(message);
                }
            }

            @Override
            public void onError(Message message, RongIMClient.ErrorCode errorCode) {
                Logger.e("文本消息发送失败:" + errorCode.getValue() + "," + errorCode.getMessage());
                if (messageListener != null) {
                    messageListener.onFailure(errorCode);
                }
            }
        });
    }

    /**
     * 发送文本消息
     *
     * @param type
     * @param targetId
     * @param text
     * @param messageListener
     */
    public void sendTextMessage(Conversation.ConversationType type, String targetId, String text, final OnMessageListener messageListener) {
        sendTextMessage(type, targetId, text, null, messageListener);
    }

    /**
     * 发送游戏文本消息
     *
     * @param type
     * @param targetId
     * @param text
     * @param messageListener
     */
    public void sendGameTextMessage(Conversation.ConversationType type, String targetId, String text, final OnMessageListener messageListener) {
        GameTextMessage textMessage = GameTextMessage.obtain(text);
        RongIMClient.getInstance().sendMessage(type, targetId, textMessage, null, null, new IRongCallback.ISendMessageCallback() {
            @Override
            public void onAttached(Message message) {
                Logger.e("文本消息发送中:" + message.getSentStatus());
                if (messageListener != null) {
                    messageListener.onProgress(message);
                }
            }

            @Override
            public void onSuccess(Message message) {
                Logger.e("文本消息发送成功");
                if (messageListener != null) {
                    messageListener.onSuccess(message);
                }
            }

            @Override
            public void onError(Message message, RongIMClient.ErrorCode errorCode) {
                Logger.e("文本消息发送失败:" + errorCode.getValue() + "," + errorCode.getMessage());
                if (messageListener != null) {
                    messageListener.onFailure(errorCode);
                }
            }
        });
    }


    /**
     * 发送图片消息
     *
     * @param type
     * @param targetId
     * @param thumbUri
     * @param imageUri
     * @param extra
     * @param messageListener
     */
    public void sendImageMessage(Conversation.ConversationType type, String targetId, String thumbUri, String imageUri
            , RcExtra extra, final OnMessageListener messageListener) {
        ImageMessage imageMessage = ImageMessage.obtain(Uri.parse(FILE_SCHEMA + thumbUri), Uri.parse(FILE_SCHEMA + imageUri));
        if (extra != null) {
            imageMessage.setExtra(JSON.toJSONString(extra));
        }
        RongIMClient.getInstance().sendImageMessage(type, targetId
                , imageMessage, null, null, new RongIMClient.SendImageMessageCallback() {
                    @Override
                    public void onAttached(Message message) {
                        if (messageListener != null) {
                            messageListener.onProgress(message);
                        }
                    }

                    @Override
                    public void onError(Message message, RongIMClient.ErrorCode errorCode) {
                        Logger.e("图片发送失败:" + errorCode.getValue() + ","
                                + errorCode.getMessage());
                        if (messageListener != null) {
                            messageListener.onFailure(errorCode);
                        }
                    }

                    @Override
                    public void onSuccess(Message message) {
                        Logger.e("图片发送成功");
                        if (messageListener != null) {
                            messageListener.onSuccess(message);
                        }
                    }

                    @Override
                    public void onProgress(Message message, int i) {

                    }
                });
    }

    /**
     * 发送附加信息的语音消息
     *
     * @param type
     * @param targetId
     * @param voicePath
     * @param duration
     * @param extra
     * @param messageListener
     */
    public void sendVoiceMessage(Conversation.ConversationType type, String targetId
            , String voicePath, int duration, RcExtra extra, final OnMessageListener messageListener) {
        VoiceMessage voiceMessage = VoiceMessage.obtain(Uri.parse(FILE_SCHEMA + voicePath), duration);
        if (extra != null) {
            voiceMessage.setExtra(JSON.toJSONString(extra));
        }
        RongIMClient.getInstance().sendMessage(type, targetId, voiceMessage, null, null, new IRongCallback.ISendMessageCallback() {
            @Override
            public void onAttached(Message message) {
                if (messageListener != null) {
                    messageListener.onProgress(message);
                }
            }

            @Override
            public void onSuccess(Message message) {
                Logger.e("音频消息发送成功:" + ((VoiceMessage) message.getContent()).getUri() + "," + (((VoiceMessage) message.getContent()).getDuration()));
                if (messageListener != null) {
                    messageListener.onSuccess(message);
                }
            }

            @Override
            public void onError(Message message, RongIMClient.ErrorCode errorCode) {
                Logger.e("音频消息发送失败:" + errorCode.getValue() + "," + errorCode.getMessage());
                if (messageListener != null) {
                    messageListener.onFailure(errorCode);
                }
            }
        });
    }

    /**
     * 发送语音消息
     *
     * @param type
     * @param targetId
     * @param voicePath
     * @param duration
     * @param messageListener
     */
    public void sendVoiceMessage(Conversation.ConversationType type, String targetId, String voicePath, int duration, final OnMessageListener messageListener) {
        sendVoiceMessage(type, targetId, voicePath, duration, null, messageListener);
    }

    /**
     * 获取会话列表
     */
    public void getConversationList(final OnConversationListener onConversationListener) {
        Objects.requireNonNull(onConversationListener);
        RongIMClient.getInstance().getConversationList(new RongIMClient.ResultCallback<List<Conversation>>() {
            @Override
            public void onSuccess(List<Conversation> conversations) {
                if (conversations == null) {
                    onConversationListener.onResult(new ArrayList<LConversation>());
                    return;
                }
                final List<LConversation> conversationList = new ArrayList<>();
                final Map<String, LConversation> convMap = new HashMap<>();
                for (Conversation conv : conversations) {
                    if (conv.getConversationType() == Conversation.ConversationType.SYSTEM) {
                        //过滤系统消息
                        continue;
                    }
                    if (conv.getConversationType() == Conversation.ConversationType.PRIVATE
                            && !DataManager.isMyFriend(conv.getTargetId())) {
                        //过滤新朋友消息
                        continue;
                    }
                    LConversation cc = new LConversation(conv);
                    if (TextUtils.isEmpty(cc.getPortraitUrl())) {
                        convMap.put(cc.getTargetId(), cc);
                    }
                    conversationList.add(cc);
                }
                if (convMap.isEmpty()) {
                    //均有头像直接回调
                    onConversationListener.onResult(conversationList);
                    return;
                }
                UserCacheMgr.getInstance().getUsersFromDB(new UserCacheMgr.OnUsersCallback() {
                    @Override
                    public void callback(List<LUser> userList) {
                        for (IUser user : userList) {
                            LConversation c = convMap.get(user.getUserId());
                            if (c != null) {
                                c.setConversationTitle(user.getNickName());
                                c.setPortraitUrl(user.getPhoto());
                                convMap.remove(user.getUserId());
                            }
                        }
                        onConversationListener.onResult(conversationList);
                    }
                }, convMap.keySet().toArray(new String[]{}));
            }

            @Override
            public void onError(RongIMClient.ErrorCode errorCode) {
                onConversationListener.onError(errorCode);
            }
        });
    }

    /**
     * 删除会话
     *
     * @param conversationType
     * @param targetId
     */
    public void deleteConversation(Conversation.ConversationType conversationType, final String targetId) {
        RongIMClient.getInstance().removeConversation(conversationType, targetId
                , new RongIMClient.ResultCallback<Boolean>() {
                    @Override
                    public void onSuccess(Boolean aBoolean) {
                        if (aBoolean) {
                            Logger.e("会话删除成功：" + targetId);
                        }
                    }

                    @Override
                    public void onError(RongIMClient.ErrorCode errorCode) {

                    }
                });
    }

    /**
     * 删除一条会话
     *
     * @param iConversation
     */
    public void deleteConversation(final IConversation iConversation) {
        RongIMClient.getInstance().removeConversation(iConversation.getConversationType(), iConversation.getTargetId()
                , new RongIMClient.ResultCallback<Boolean>() {
                    @Override
                    public void onSuccess(Boolean aBoolean) {
                        if (aBoolean) {
                            Logger.e("会话删除成功：" + iConversation.getTargetId());
                        }
                    }

                    @Override
                    public void onError(RongIMClient.ErrorCode errorCode) {

                    }
                });
    }

    /**
     * 会话标记所有信息已读
     *
     * @param iConversation
     */
    public void clearConversationMsgUnreadStatus(IConversation iConversation, RongIMClient.ResultCallback<Boolean> callback) {
        RongIMClient.getInstance().clearMessagesUnreadStatus(iConversation.getConversationType()
                , iConversation.getTargetId(), callback);
    }

    /**
     * 标记指定目标和类型的信息已读
     *
     * @param type
     * @param targetId
     * @param callback
     */
    public void clearMsgUnreadStatus(Conversation.ConversationType type, String targetId, RongIMClient.ResultCallback<Boolean> callback) {
        RongIMClient.getInstance().clearMessagesUnreadStatus(type, targetId, callback);
    }

    /**
     * 设置消息的接收状态
     *
     * @param messageId
     * @param receivedStatus
     */
    public void setMessageReceivedStatus(int messageId, Message.ReceivedStatus receivedStatus) {
        RongIMClient.getInstance().setMessageReceivedStatus(messageId, receivedStatus, new RongIMClient.ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean aBoolean) {
                Logger.e("更新消息的接收状态:" + aBoolean);
            }

            @Override
            public void onError(RongIMClient.ErrorCode errorCode) {

            }
        });
    }

    /**
     * 获取某条消息的前10条消息
     * -1表示最新
     *
     * @param convType
     * @param targetId
     * @param msgId
     * @param callback
     */
    public void getHistoryMessages(Conversation.ConversationType convType, String targetId, int msgId, RongIMClient.ResultCallback<List<Message>> callback) {
        RongIMClient.getInstance().getHistoryMessages(convType
                , targetId, msgId, AppConfig.PAGE_SIZE, callback);
    }

    /**
     * 获取远程在线历史消息列表
     *
     * @param convType
     * @param targetId
     * @param datetime
     * @param callback
     */
    public void getRemoteHistoryMessages(Conversation.ConversationType convType, String targetId, long datetime, RongIMClient.ResultCallback<List<Message>> callback) {
        RongIMClient.getInstance().getRemoteHistoryMessages(convType, targetId, datetime, AppConfig.PAGE_SIZE, callback);
    }

    /**
     * 插入一条本地消息
     *
     * @param targetId
     * @param messageContent
     * @param resultCallback
     */
    public void insertMessage(final Conversation.ConversationType type, final String targetId, final MessageContent messageContent, final RongIMClient.ResultCallback<Message> resultCallback) {
        RongIMClient.getInstance().insertMessage(type, targetId, RcUser.getInstance().getUserId(),
                messageContent, TimeUtils.getNowMills(), resultCallback);
    }

    /**
     * 删除一条或多条本地消息
     *
     * @param msgIds
     * @param resultCallback
     */
    public void deleteMessage(final int[] msgIds, final RongIMClient.ResultCallback<Boolean> resultCallback) {
        try {
            RongIMClient.getInstance().deleteMessages(msgIds, resultCallback);
        } catch (Exception e) {
        }
    }

    /**
     * 搜索历史消息
     *
     * @param targetId
     * @param keyword
     * @param resultCallback
     */
    public void searchMessages(Conversation.ConversationType type, String targetId, String keyword, RongIMClient.ResultCallback<List<Message>> resultCallback) {
        RongIMClient.getInstance().searchMessages(type, targetId
                , keyword, 0, 0, resultCallback);
    }

    public void insertIncomingMessage(Conversation.ConversationType type, String targetId, String senderUserId, Message.ReceivedStatus receivedStatus, MessageContent content, RongIMClient.ResultCallback<Message> callback) {
        this.insertIncomingMessage(type, targetId, senderUserId, receivedStatus, content, System.currentTimeMillis(), callback);
    }

    public void insertIncomingMessage(Conversation.ConversationType type, String targetId, String senderUserId, Message.ReceivedStatus receivedStatus, MessageContent content, long sentTime, final RongIMClient.ResultCallback<Message> callback) {
        MessageTag tag = content.getClass().getAnnotation(MessageTag.class);
        if (tag != null && (tag.flag() & 1) == 1) {
            RongIMClient.getInstance().insertIncomingMessage(type, targetId, senderUserId, receivedStatus, content, sentTime, new RongIMClient.ResultCallback<Message>() {
                public void onSuccess(Message message) {
                    if (callback != null) {
                        callback.onSuccess(message);
                    }

                    EventBus.getDefault().post(message);
                }

                public void onError(RongIMClient.ErrorCode e) {
                    if (callback != null) {
                        callback.onError(e);
                    }

                    EventBus.getDefault().post(e);
                }
            });
        } else {
            Logger.e("insertMessage Message is missing MessageTag.ISPERSISTED");
        }

    }

    public void insertOutgoingMessage(Conversation.ConversationType type, String targetId, Message.SentStatus sentStatus, MessageContent content, RongIMClient.ResultCallback<Message> callback) {
        this.insertOutgoingMessage(type, targetId, sentStatus, content, System.currentTimeMillis(), callback);
    }

    public void insertOutgoingMessage(Conversation.ConversationType type, String targetId, Message.SentStatus sentStatus, MessageContent content, long sentTime, final RongIMClient.ResultCallback<Message> callback) {
        MessageTag tag = content.getClass().getAnnotation(MessageTag.class);
        if (tag != null && (tag.flag() & 1) == 1) {
            RongIMClient.getInstance().insertOutgoingMessage(type, targetId, sentStatus, content, sentTime, new RongIMClient.ResultCallback<Message>() {
                public void onSuccess(Message message) {
                    if (callback != null) {
                        callback.onSuccess(message);
                    }

                    EventBus.getDefault().post(message);
                }

                public void onError(RongIMClient.ErrorCode e) {
                    if (callback != null) {
                        callback.onError(e);
                    }

                    EventBus.getDefault().post(e);
                }
            });
        } else {
            Logger.e("insertMessage Message is missing MessageTag.ISPERSISTED");
        }

    }

    public boolean isBroadcastSentByDB(String groupId) {
        LBroadcast broadcast = DataSupport.where("groupId=? and userId=?"
                , groupId, RcUser.getInstance().getUserId()).findLast(LBroadcast.class);
        return broadcast != null && broadcast.getCount() > 0;
    }

}
